package com.balloon.gateway.security.handler;

import com.balloon.gateway.redis.RedisUtils;
import com.balloon.gateway.comm.ResultVOUtils;
import com.balloon.gateway.utils.JwtUtil;
import com.balloon.gateway.security.user.entity.SystemUser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author liaofuxing
 * @version 1.0.0
 * @date 2022/3/8 12:32
 * @description 登录成功Handler
 */
@Component
public class DefaultAuthenticationSuccessHandler implements ServerAuthenticationSuccessHandler {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        return Mono.defer(() -> Mono.just(webFilterExchange.getExchange().getResponse()).flatMap(response -> {
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            // 生成JWT token
            Map<String, Object> map = new HashMap<>();
            SystemUser systemUser = (SystemUser) authentication.getPrincipal();
            map.put("userId", systemUser.getId());
            map.put("username", systemUser.getUsername());
            map.put("roles", systemUser.getAuthorities());
            ObjectMapper objectMapper = new ObjectMapper();
            String subject;
            String json = "";
            try {
                subject = objectMapper.writeValueAsString(map);

                String token = JwtUtil.createJWT(systemUser.getId().toString(), systemUser.getUsername(), subject, 30000);
                // 将JWT 存入redis
                RedisUtils redisUtils = new RedisUtils(stringRedisTemplate);
                redisUtils.setEx("SYSTEM_USER_INFO:" + systemUser.getUsername(), token, 30, TimeUnit.MINUTES);
                Map<String, Object> tokenMap = new HashMap<>(2);
                tokenMap.put("username", systemUser.getUsername());
                tokenMap.put("token", token);
                json = objectMapper.writeValueAsString(ResultVOUtils.login_success(tokenMap));

            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return response.writeWith(Mono.just(dataBufferFactory.wrap(json.getBytes())));
        }));
    }
}